/** @jsx jsx */
import React, {
    useEffect,
    useLayoutEffect,
    useState,
    useCallback,
    useMemo,
    useRef
} from "react";
import {
    message,
    Popover,
    Spin,
    Tabs,
    Badge,
    Modal,
    ConfigProvider
} from "antd";
import {
    connect,
    useDispatch,
    useSelector
} from "react-redux";
import BtnAlert from "../../common/component/btnAlert";
import Header from "../header";
import Todo from "./todo";
import Message from "./message";
import ClassNotice from './classNotice'
import SchoolNotice from './schoolNotice'
import Chat from "./chat";
import md5 from 'md5'
import CustomModal from "../../common/component/modal";
import {
    LgPopLayer,
    LgButton
} from 'lancoo-web-ui'
import {
    judgeJson,
    getQueryVariable
} from "../../util";
import axiosMethod from "../../util/axios";
import CONFIG from "../../util/config";
import axios from "axios";
import TaskProcess from '../taskProcess'
import { jsx } from '@emotion/react'
import 'antd/dist/antd.variable.min.css';
import "./common.scss";
import "./index.scss";
import useGetThem from "../../hooks/useGetThem";

const {
    appAddr
} = CONFIG;
const {
    TabPane
} = Tabs;

var hasChat = true

const flowChartImg = require('./images/flowChartImg.png')
const cardBg = require('./images/cardBg.png')

function Main(props) {


    let {
        userInfo,
        sysAddrInfo,
        scheduleInfo,
        currentIdentity,
        sysInfo,
        noticeAddr,
        noticePublishInfo,
        alertInfo,
        isEdu,
        chatCount,
        skin,
    } = useSelector(state => state);
    const {defaultColor, hoverColor} = useGetThem(skin)

    let reconnectCount = 0

    const dispatch = useDispatch();
    const [currentKind, setCurrentKind] = useState();
    const [loadVisible, setLoadVisible] = useState(false);
    const [updateKindList, setUpdateKindList] = useState([]);
    const [wsClinet, setWsClinet] = useState(null)
    const [remindSocket, setRemindSocket] = useState(null)
    const [chatList, setChatList] = useState([])

    const HeaderCom = useMemo(() => {
        return <Header title='消息中心' />;
    }, []);
    const BodyCom = useMemo(() => {
        let dom = "";
        if (currentKind === "待办事项" || currentKind === 'todo') {
            dom = < Todo />;
        }
        if (currentKind === '班级通知' || currentKind === 'classNotice') {
            dom = < ClassNotice />
        }
        if (currentKind === "部门通知" || currentKind === 'schoolNotice') {
            dom = < SchoolNotice />;
        }
        if (currentKind === "交流消息" || currentKind === 'chat') {
            dom = < Chat chatList={
                chatList || []
            }
            />;
        }
        if (currentKind === "系统提醒" || currentKind === 'message') {
            dom = < Message />;
        }
        return dom;
    }, [currentKind, chatList]);

    const getWebAddr = useCallback((sysId, func) => {
        //网站信息
        axiosMethod({
            type: "get",
            url: "/api/commons/system/getServerInfo",
            body: {
                sysIds: sysId
            },
            callback: function (res) {
                console.log(res)
                func(res[0]?.webSvrAddr || '');
            }
        });
    }, [userInfo]);

    const getWsAddr = useCallback((sysId, func) => {
        //网站信息
        axiosMethod({
            type: "get",
            url: "/api/commons/system/getServerInfo",
            body: {
                sysIds: sysId
            },
            callback: function (res) {
                func(res[0]?.wsSvrAddr || '');
            }
        });
    }, []);

    const Http = useCallback(({
        url,
        method,
        params,
        func
    }) => {
        axios.request({
            method,
            url,
            data: params,
            headers: {
                Authorization: 'X-Token=' + sessionStorage.getItem('token')
            },
        }).then((res) => {
            func(res.data)
        })
    }, [userInfo])

    const setReadInfo = useCallback((type, value, number, list = updateKindList) => {
        if (!number) {
            let arr = JSON.parse(JSON.stringify(list));
            setUpdateKindList(arr);
            return
        }
        //手动设置是否存在未读消息
        let arr = JSON.parse(JSON.stringify(list));
        arr.forEach((item) => {
            if (item.key === type && item.count != number) {
                item.count = number || 0;
            }
        })
        setUpdateKindList(arr);
    }, [updateKindList]);

    const getIPAndPort = (url) => {
        var urlObj = new URL(url);
        var ip = urlObj.hostname;
        var port = parseInt(urlObj.port) + 1;

        return ip + ':' + port
    }


    function sumUnReadCount(objArray) {
        if (objArray.length === 0) {
            return 0;
        }

        return objArray.reduce((total, obj) => {
            if (obj.unReadCount !== undefined) {
                return total + obj.unReadCount;
            }
            return total;
        }, 0);
    }

    const judgeChatCount = useCallback(() => { //在线交流需要额外判断是否存在未读消息
        console.log(hasChat)
        console.log(isEdu)
        // if (!hasChat || isEdu) {
        //     return
        // }
        //获取在线交流地址
        console.log('sssssssssssssssssssssss')
        getWebAddr('460', function (wsAddr) {
            console.log(wsAddr)
            if (wsAddr) {
                axiosMethod({
                    url: wsAddr + '/api/commons/school/system/info',
                    body: {
                        token: sessionStorage.getItem('token'),
                        eduId: userInfo.SchoolID
                    },
                    showError:false,
                    callback: (result) => {
                        console.log(result)
                        let chatUrl = result.chatWs
                        // if (wsAddr.indexOf('https') > -1) {
                        //     chatUrl = 'wss://' + getIPAndPort(wsAddr) + '/chat'
                        // } else {
                        //     chatUrl = 'ws://' + getIPAndPort(wsAddr) + '/chat'
                        // }
                        window.chatSocket && window.chatSocket.close()
                        let wsClinet = new WebSocket(chatUrl)
                        window.chatsocket = wsClinet
                        wsClinet.onopen = () => {
                            wsClinet.send(JSON.stringify({
                                "msgType": "3",
                                "clientType": "5",
                                "token": sessionStorage.getItem('token'),
                                "data": {
                                    "userId": userInfo.UserID
                                }
                            }))
                        };
                        wsClinet.onmessage = (e) => {
                            let result = JSON.parse(e.data)
                            if (result.code == 200) {
                                switch (result.msgType) {
                                    case 1:
                                        wsClinet.send(JSON.stringify({
                                            "msgType": 100,
                                            "clientType": 5,
                                            "token": sessionStorage.getItem('token'),
                                            "data": {
                                                "clientType": 5,
                                                'msgId': result.data.msgId,
                                                'receiverId': result.data.senderId,
                                                'receiverName': result.data.senderId || '',
                                                'schoolId': userInfo.SchoolID,
                                                'sessionType': result.msgType,
                                                'receiverAvatarPath':result?.data?.senderAvatarPath || ""
                                            }
                                        }))
                                        wsClinet.send(JSON.stringify({
                                            "msgType": 4,
                                            "clientType": 5,
                                            "token": sessionStorage.getItem('token'),
                                            "data": {}
                                        }))
                                        break;
                                    case 2:
                                        wsClinet.send(JSON.stringify({
                                            "msgType": 100,
                                            "clientType": 5,
                                            "token": sessionStorage.getItem('token'),
                                            "data": {
                                                "clientType": 5,
                                                'msgId': result.data.msgId,
                                                'groupId':result?.data.groupId,
                                                'groupName':result?.data.groupName,
                                                'receiverId': result.data.senderId,
                                                'receiverName': result.data.senderId || '',
                                                'schoolId': userInfo.SchoolID,
                                                'sessionType': result.msgType,
                                                'receiverAvatarPath': result?.data?.avatarPath || "",
                                            }
                                        }))
                                        wsClinet.send(JSON.stringify({
                                            "msgType": 4,
                                            "clientType": 5,
                                            "token": sessionStorage.getItem('token'),
                                            "data": {}
                                        }))
                                        break;
                                    case 3:
                                        wsClinet.send(JSON.stringify({
                                            "msgType": 10,
                                            "clientType": 5,
                                            "token": sessionStorage.getItem('token'),
                                            "data": {}
                                        }))
                                        break;
                                    case 4:
                                        let currentChatList = result.data || []
                                        currentChatList.length && currentChatList.sort(function (a, b) {
                                            if (a.seat === 1 && b.seat === 0) {
                                                return -1; // a在b前面
                                            } else if (a.seat === 0 && b.seat === 1) {
                                                return 1; // a在b后面
                                            } else if (a.seat === 1 && b.seat === 1) {
                                                return b.levelNum - a.levelNum; // levelNum越大，越靠前
                                            } else {
                                                return 0; // 保持原有顺序
                                            }
                                        });
                                        let msgChatCount = sumUnReadCount(currentChatList)
                                        dispatch({
                                            type: 'SET_CHATCOUNT',
                                            data: msgChatCount
                                        })
                                        setChatList(result.data)
                                        break;
                                    case 7:
                                        wsClinet.send(JSON.stringify({
                                            "msgType": "4",
                                            "clientType": "5",
                                            "token": sessionStorage.getItem("token"),
                                            "data": {}
                                        }))
                                        message.success('移除会话成功')
                                        break;
                                    case 10:
                                        wsClinet.send(JSON.stringify({
                                            "msgType": "4",
                                            "clientType": "5",
                                            "token": sessionStorage.getItem("token"),
                                            "data": {}
                                        }))
                                        break;
                                    case 11:
                                    case 12:
                                        wsClinet.send(JSON.stringify({
                                            "msgType": "4",
                                            "clientType": "5",
                                            "token": sessionStorage.getItem("token"),
                                            "data": {}
                                        }))
                                        message.success('操作成功')
                                        break;
                                    case 13:
                                    case 100:
                                        wsClinet.send(JSON.stringify({
                                            "msgType": "4",
                                            "clientType": "5",
                                            "token": sessionStorage.getItem("token"),
                                            "data": {}
                                        }))
                                        break;
                                    default:
                                        break;
                                }
                            } else {
                                dispatch({
                                    type: "SET_ALERTINFO",
                                    data: {}
                                })
                                // message.warn(result.msg)
                            }
                        }
                        wsClinet.onerror = () => {
                            console.log(reconnectCount)
                            if (reconnectCount < 5) {
                                setTimeout(() => {
                                    judgeChatCount()
                                }, 2000);
                                reconnectCount++
                            }
                        }
                        wsClinet.onclose = () => {
                            console.log(reconnectCount)
                            if (reconnectCount < 5) {
                                setTimeout(() => {
                                    judgeChatCount()
                                }, 2000);
                                reconnectCount++
                            }
                        }
                    }
                })
            }
        })
    }, [chatList]);


    const getReadInfo2 = useCallback((res) => { //socket获取的消息
        let list = JSON.parse(JSON.stringify(updateKindList));
        list.forEach((item) => {
            if (Number(res.systemCount) && item.name == '系统提醒') { //系统消息
                item.noRead = true;
                item.count = Number(res.systemCount)
            }
            if (Number(res.todoCount) && item.name == '待办事项') { //班级通知
                item.noRead = true;
                item.count = Number(res.todoCount)
            }
            if (Number(res.noticeClassCount) && item.name == '班级通知') { //班级通知
                item.noRead = true;
                item.count = Number(res.noticeClassCount)
            }
            // if ( item.name == '交流消息') {   //班级通知
            //     item.noRead = true;
            //     item.count = Number(res.chatCount)
            // }
            if (Number(res.noticeSchoolCount) && item.name == '部门通知') { //部门通知
                item.noRead = true;
                item.count = Number(res.noticeSchoolCount)
            }
        })
        setUpdateKindList(list);
    }, [updateKindList]);

    const getNoticeAddr = useCallback(() => {
        getWebAddr("264", function (data) {
            dispatch({
                type: 'SET_NOTICEADDR',
                data: data
            })
        })
        getWebAddr("264", function (data) {
            dispatch({
                type: 'SET_OFFICEURL',
                data: data
            })
        })
    }, [dispatch, getWebAddr]);

    const changeKind = useCallback((value) => {
        setCurrentKind(value);
        getNewRemindCount()
    }, []);

    const changeAppLoad = useCallback((value) => {
        setLoadVisible(value);
    }, []);

    const createNewRemindSocket = useCallback(() => {
        let socketUrl = ''
        getWsAddr('210', function (data) {
            if (data.indexOf('ws://') > -1) {
                socketUrl = data
            } else {
                if (data.indexOf('https') > -1) {
                    socketUrl = 'wss://' + data.split('https://')[1] + '/api/websocket/'
                } else {
                    socketUrl = 'ws://' + data.split('http://')[1] + '/api/websocket/'
                }
            }

            // if (process.env.NODE_ENV === 'development') {
            //      socketUrl = 'ws://192.168.129.33:11211/message-center/api/websocket/'
            // }
            window.remindSocket && window.remindSocket.close();
            let socket = new WebSocket(socketUrl);
            setRemindSocket(socket)
            window.remindSocket = socket;
            socket.onopen = function () {
                socket.send(JSON.stringify({
                    messageType: 1,
                    clientType: 4,
                    userId: userInfo.UserID,
                    encryptionCode: md5(userInfo.UserID).split('').reverse().join(''),
                    param: {
                        userId: userInfo.UserID,
                        userType: userInfo.UserType,
                        schoolId: userInfo.SchoolID
                    }
                }))
            }
            socket.onmessage = function (e) {
                let result = judgeJson(e.data) ? JSON.parse(e.data) : {};
                switch (result.pushType || result.code) {
                    case 1002:
                        socket.send(JSON.stringify({
                            messageType: 2,
                            clientType: 4,
                            userId: userInfo.UserID,
                            encryptionCode: md5(userInfo.UserID).split('').reverse().join(''),
                            param: {
                                userId: userInfo.UserID,
                                userType: userInfo.UserType,
                                schoolId: userInfo.SchoolID
                            }
                        }))
                        break;
                    case 1200:
                        result.data && getReadInfo2(result.data)
                        break;
                    case 1000:
                        message.warn('非法连接')
                        window.remindSocket.close()
                        break;
                    case 999:
                        window.remindSocket.close()
                        break;
                    default:
                        break;
                }
            }
        })
    }, [userInfo, getReadInfo2, getWsAddr])

    const getNewRemindCount = () => {

    }

    /**
     * 
     * @param {Event} e 
     * @param {Number} type 1 预览 2 保存 3 发布 4 取消
     */
    const handleNoticePublish = (e, type) => {
        e && e.stopPropagation()
        let publishInfo = {
            visible: false,
            currentKind: noticePublishInfo?.currentKind,
            url: noticePublishInfo?.url || '',
            title: noticePublishInfo?.showUrgent ? '发布紧急通知' : noticePublishInfo?.currentKind == 3 ? '发布班级通知' : '发布学校通知',
        }
        dispatch({
            type: 'SET_NOTICEPUBLISHINFO',
            data: publishInfo
        })
    }

    const setHiddenOnlineChat = () => {
        hasChat = false
    }

    useEffect(() => {
        ConfigProvider.config({
            theme: {
                primaryColor: defaultColor,
            },
        });
    }, [defaultColor])

    useEffect(() => {
        getNoticeAddr()
        window.addEventListener('message', function (e) {
            console.log(e)
            let data = JSON.parse(e.data)
            if (data?.close) {
                handleNoticePublish('')
                window._getSchoolNotice && typeof window._getSchoolNotice === 'function' && window._getSchoolNotice()
                getNewRemindCount()
            }
        })
    }, [getNoticeAddr])

    useLayoutEffect(() => {
        //挂载全局函数到window，方便各模块调用
        window.getWebAddr = getWebAddr;
        window.changeAppLoad = changeAppLoad;
        // window.getReadInfo = getReadInfo;
        window.setReadInfo = setReadInfo;
        window.getNewRemindCount = getNewRemindCount
        window.setHiddenOnlineChat = setHiddenOnlineChat
        // window.recordReadTime = recordReadTime;

    }, [changeAppLoad, getWebAddr, setReadInfo]);


    useLayoutEffect(() => {
        judgeChatCount();
    }, []);


    useEffect(() => {
        if (updateKindList.length <= 0 || remindSocket || wsClinet) {
            return
        }
        createNewRemindSocket()
    }, [updateKindList, remindSocket, wsClinet])


    useEffect(() => {
        let favicon = document.getElementById("favicon");
        favicon.href = './favicon.ico'
        axiosMethod({
            url: '/api/commons/system/getSystemModular?userType=' + userInfo.UserType,
            body: {
                userType: userInfo.UserType,
                schoolId: userInfo.SchoolID,
                beEdu: isEdu ? 1 : 0
            },
            callback: function (result) {
                if (result) {
                    let moduleArr = result.split(',')
                    let moduleInfo = []
                    moduleArr.forEach((item, index) => {
                        moduleInfo.push({
                            key: item,
                            name: item,
                            noRead: false
                        })
                    });
                    let targetTab = getQueryVariable('currentTab')
                    if (!targetTab) {
                        setCurrentKind(moduleInfo[0].key)
                    } else {
                        let tabStr = decodeURIComponent(targetTab)
                        switch (tabStr) {
                            case 'todo':
                                tabStr = '待办事项'
                                break;
                            case 'classNotice':
                                tabStr = '班级通知'
                                break;
                            case 'schoolNotice':
                                tabStr = '部门通知'
                                break;
                            default:
                                break;
                        }
                        setCurrentKind(tabStr)
                    }
                    setUpdateKindList(moduleInfo)
                }
            }
        })
    }, [userInfo])

    return (
        <ConfigProvider>
            <div className='app_main'>
            {HeaderCom}
            <Spin wrapperClassName="main_load" spinning={loadVisible} tip="加载中...">
                <div className="top_option_area">
                    <div className="option_tabs">
                        <Tabs className="body_tab" activeKey={currentKind} defaultActiveKey={currentKind} onChange={changeKind}>
                            {
                                updateKindList.length > 0 &&
                                updateKindList.map((item, index) => (
                                    <TabPane tab={
                                        <Badge count={item.key === '交流消息' ? chatCount : item.count}>
                                            <span
                                               css={{
                                                color: currentKind == item.name ? defaultColor : 'inherit',
                                                fontWeight: currentKind == item.name ? '700' : 'inherit',
                                                '&:hover':{
                                                    color: hoverColor
                                                }
                                            }}>
                                                {item.name}
                                            </span>
                                        </Badge>

                                    } key={item.key}></TabPane>
                                ))
                            }
                        </Tabs>
                    </div>
                </div>
                {/* <div className="main_body"> */}
                {BodyCom}
                {/* </div> */}
                {/* <LgPageFooter>&copy;蓝鸽科技 版权所有</LgPageFooter> */}
            </Spin>

            <Modal
                visible={scheduleInfo.visible}
                onOk={() => { }}
                onCancel={() => {
                    dispatch({
                        type: 'SET_SCHEDULEINFO',
                        data: {
                            visible: false
                        }
                    })
                }}

                footer={null}
                destroyOnClose={true}
                width={480}
                centered
                bodyStyle={{
                    padding: '16px'
                }}
            >
                {
                    scheduleInfo?.scheduleObj ?
                        <>
                            <span class="schedule-card">
                                <i class="schedule-close"></i>
                                <p class="title">日程邀请</p>
                                <div class="content-box">
                                    <p class="active-type">
                                        <span class="schedule-type" title={scheduleInfo?.scheduleObj?.scheduleTitle}>{scheduleInfo?.scheduleObj?.scheduleTitle || '--'}</span>
                                    </p>
                                    <p>
                                        <span class="left title2">发起人：</span>
                                        <span class="schedule-originator-avatar" ></span>
                                        <span class="schedule-originator-name">{scheduleInfo?.scheduleObj?.userName || '--'}</span>
                                        <span class="schedule-originator-id">({scheduleInfo?.scheduleObj?.userId || '--'})</span>
                                    </p>
                                    <p>
                                        <span class="left title3">会议时间：</span>
                                        <span class="schedule-time">{`${scheduleInfo?.scheduleObj?.scheduleDate} ${scheduleInfo?.scheduleObj?.startTime}~${scheduleInfo?.scheduleObj?.endTime}`}</span>
                                    </p>
                                    <p>
                                        <span class="left title4">会议地点：</span>
                                        <span class="schedule-place" title={scheduleInfo?.scheduleObj?.scheduleLocation}>{scheduleInfo?.scheduleObj?.scheduleLocation || '--'}</span>
                                    </p>
                                    <p class="schedule-remark">
                                        <span class="left title5">日程描述：</span>
                                        <span class="schedule-content" title={scheduleInfo?.scheduleObj?.scheduleContent}>{scheduleInfo?.scheduleObj?.scheduleContent || '--'}</span>
                                    </p>
                                </div>
                                <div class="schedule-footer">
                                    <span class="schedule-yes" onClick={() => { typeof scheduleInfo.onConfirm === 'function' && scheduleInfo.onConfirm(2) }}>确认参会</span>
                                    <span class="schedule-no" onClick={() => { typeof scheduleInfo.onConfirm === 'function' && scheduleInfo.onConfirm(3) }}>拒绝参会</span>
                                    <span class="schedule-wait" onClick={() => {
                                        dispatch({
                                            type: 'SET_SCHEDULEINFO',
                                            data: {
                                                visible: false
                                            }
                                        })
                                    }}>待定</span>
                                </div>
                            </span>
                        </> : ''
                }
            </Modal>

            <LgPopLayer
                title={noticePublishInfo?.title || '发布通知公告'}
                isOpen={noticePublishInfo?.visible}
                width={1200}
                height={720}
                onIconClose={() => {
                    handleNoticePublish("", 4)
                }}
                className="publish_popup"
                isShowBottom={false}
            >
                <div style={{
                    height: '100%',
                    width: '100%'
                }}>
                    {
                        noticePublishInfo?.url ?
                            <iframe
                                name="noticeFrame"
                                src={noticePublishInfo?.url}
                                width={'100%'}
                                height={'100%'}
                                scrolling='auto'
                                frameBorder={0}
                                title="publish"
                                allowtransparency={'true'}
                            /> : ''
                    }

                </div>
            </LgPopLayer>
            <BtnAlert
                visible={alertInfo.visible}
                title={alertInfo.title}
                smallTitle={alertInfo.smallTitle}
                onOk={alertInfo.onOk}
                onCancel={alertInfo.onCancel} />
            {
                (currentKind === '学校通知' || currentKind === '班级通知' )&&(userInfo?.UserType==='0'  || userInfo?.UserType==='1' || userInfo.UserType==='11')?
                    <TaskProcess
                        title="校园通知应用"
                        subtitle="校园通知"
                        processImg={flowChartImg}
                        cardBg={cardBg}
                        width={1070}
                        description={
                            <>
                                <span>"通知应用”包含:通知发布管理、通知查阅和通知管理功能模块。</span><br />
                                <span>管理者可在“通知管理”查看并管理全校所有已发布通知，可以按需撤回、删除通知、跟踪通知阅读详情、催读通知等。</span><br />
                                <span>管理员可以在“通知发布管理”模块完成通知的创建和发布，以及进行通知管理：包括跟踪通知阅读详情、催读通知、撤回通知，以及暂存未新建完成的通知。</span><br />
                                <span>用户可以在“消息中心”的通知分组下，查阅和管理所有已收到的通知。</span>
                            </>
                        }
                    /> : ''
            }
            </div>
        </ConfigProvider>
    )
}
// const mapProps = (state) => {
//     return {
//         userInfo: state.userInfo,
//         sysAddrInfo: state.sysAddrInfo,
//         currentIdentity: state.currentIdentity,
//         sysInfo: state.sysInfo,
//         alertInfo: state.alertInfo,
//         noticeAddr: state.noticeAddr,
//         scheduleInfo: state.scheduleInfo,
//         noticePublishInfo: state.noticePublishInfo,
//         chatCount: state.chatCount,
//         isEdu: state.isEdu
//     }
// }
// export default connect(mapProps)(Main);      

export default Main;      